Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for Proof Key For Code Exchange (PKCE) in OIDC social providers #4033

Closed
wants to merge 4 commits into from

Conversation

OskarsPakers
Copy link

Adds support for Proof Key For Code Exchange (PKCS) in OIDC social providers according to rfc7636 https://datatracker.ietf.org/doc/html/rfc7636

Related issue(s)

#4009

Checklist

  • I have read the contributing guidelines.
  • I have referenced an issue containing the design document if my change
    introduces a new feature.
  • I am following the
    contributing code guidelines.
  • I have read the security policy.
  • I confirm that this pull request does not address a security
    vulnerability. If this pull request addresses a security vulnerability, I
    confirm that I got the approval (please contact
    [email protected]) from the maintainers to push
    the changes.
  • I have added tests that prove my fix is effective or that my feature
    works.
  • I have added or changed the documentation.

Further Comments

Supports methods s256 and plain.
AuthCodeURLOptions method signature does not return err, therefore can`t return an error. Should we change the signature of the method and lift the functionality up to the strategy code?

@CLAassistant
Copy link

CLAassistant commented Aug 13, 2024

CLA assistant check
All committers have signed the CLA.

@OskarsPakers OskarsPakers changed the title Add support for Proof Key For Code Exchange (PKCS) in OIDC social providers feat: Add support for Proof Key For Code Exchange (PKCS) in OIDC social providers Aug 13, 2024
@OskarsPakers OskarsPakers changed the title feat: Add support for Proof Key For Code Exchange (PKCS) in OIDC social providers feat: add support for Proof Key For Code Exchange (PKCS) in OIDC social providers Aug 13, 2024
@alnr alnr changed the title feat: add support for Proof Key For Code Exchange (PKCS) in OIDC social providers feat: add support for Proof Key For Code Exchange (PKCE) in OIDC social providers Aug 14, 2024
Copy link
Contributor

@hperl hperl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! This looks very good already. I have added some comments below, mostly to make sure that this code also works for registration and settings flows.

Also, I'd like to see more tests on this. So far, I could only see unit tests for the provider. We also need E2E tests that make sure that the challenge and verifier are correctly persisted and compared, with both happy and error paths covered.

@@ -96,6 +98,25 @@ func (g *ProviderGenericOIDC) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption
return options
}

func (g *ProviderGenericOIDC) addPKCSURLOptions(r ider, options []oauth2.AuthCodeOption) []oauth2.AuthCodeOption {
flow, err := g.reg.LoginFlowPersister().GetLoginFlow(context.Background(), r.GetID())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r could also be a registration flow, correct? In that case, we won't find a login flow. Also, the context needs to be bound to the user's request context, not context.Background().

I think you can just add flow.InternalContexter to the ider interface, and use r directly.

@@ -386,3 +404,34 @@ func (s *Strategy) PopulateLoginMethodIdentifierFirstCredentials(r *http.Request
func (s *Strategy) PopulateLoginMethodIdentifierFirstIdentification(r *http.Request, f *login.Flow) error {
return s.populateMethod(r, f, text.NewInfoLoginWith)
}

func SetPKCSContext(flow flow.InternalContexter, context PkcsContext) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd move this and the next method into the selfservice/flow package. There is probably also some opportunity to make a generic getter/setter, as these methods are very similar to Get/SetDuplicateCredentials.

client := s.d.HTTPClient(ctx)
ctx = context.WithValue(ctx, oauth2.HTTPClient, client.HTTPClient)
token, err = te.Exchange(ctx, code)
return token, err
switch loginFlow := flow.(type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this not work for registration flows?

if pkcsContext.Verifier != "" && (pkcsContext.Method == "S256" || pkcsContext.Method == "plain") {
return te.Exchange(ctx, code, oauth2.VerifierOption(pkcsContext.Verifier))
} else {
return nil, errors.Errorf("Invalid PKCS method: %s or empty verifier: %s", pkcsContext.Method, pkcsContext.Verifier)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a herodot error as well.

@@ -255,6 +262,17 @@ func (s *Strategy) Login(w http.ResponseWriter, r *http.Request, f *login.Flow,
}

state := generateState(f.ID.String())

if provider.Config().PKCSMethod != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also needs to be done for registration. And how about settings?

@OskarsPakers
Copy link
Author

Closing this one as it seems to be continued in #4033

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants